package com.cino.annotation;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 处理 @ConditionalOnListProperty 注解的条件类
 * 检查配置属性是否包含特定值
 */
public class OnListPropertyCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 获取注解属性
        MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(
                ConditionalOnListProperty.class.getName(), true);

        if (attributes == null) {
            return false;
        }

        // 获取属性名数组
        List<String> names;
        Object nameValue = attributes.getFirst("name");
        if (nameValue instanceof String[]) {
            String[] arr = (String[]) nameValue;
            names = Arrays.asList(arr);
        } else if (nameValue instanceof List) {
            @SuppressWarnings("unchecked")
            List<String> nameList = (List<String>) nameValue;
            names = nameList;
        } else {
            //TODO替换BusinessException
            throw new IllegalArgumentException("name 属性必须是 String[] 或 List<String> 类型");
        }
        
        if (names.isEmpty()) {
            //TODO替换BusinessException
            throw new IllegalArgumentException("name 属性不能为空");
        }

        // 获取期望的值
        Object havingValueObj = attributes.getFirst("havingValue");
        if (havingValueObj == null || !StringUtils.hasText(havingValueObj.toString())) {
            //TODO替换BusinessException
            throw new IllegalArgumentException("havingValue 属性不能为空");
        }
        String havingValue = havingValueObj.toString();

        // 获取 matchIfMissing 参数
        Object matchIfMissingObj = attributes.getFirst("matchIfMissing");
        boolean matchIfMissing = matchIfMissingObj != null && (Boolean) matchIfMissingObj;

        // 获取环境变量
        Environment environment = context.getEnvironment();

        // 检查每个属性名（支持多个属性名，只要有一个匹配即可）
        for (String name : names) {
            if (checkProperty(environment, name, havingValue, matchIfMissing)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 检查单个属性是否包含指定值
     */
    private boolean checkProperty(Environment environment, String name, String havingValue, boolean matchIfMissing) {
        // 获取属性值
        Object propertyValue = environment.getProperty(name);

        // 属性不存在的情况
        if (propertyValue == null) {
            return matchIfMissing;
        }

        // 将属性值转换为统一的列表形式
        List<String> values = convertToList(propertyValue);

        // 检查是否包含期望的值
        return values.contains(havingValue);
    }

    /**
     * 将不同类型的属性值转换为统一的 List<String>
     */
    private List<String> convertToList(Object propertyValue) {
        if (propertyValue instanceof String) {
            // 处理字符串类型（逗号分隔）
            String val = (String) propertyValue;
            return Arrays.stream(val.split(","))
                    .map(String::trim)
                    .filter(s -> !s.isEmpty())
                    .collect(Collectors.toList());
        }
        else if (propertyValue instanceof String[]) {
            // 处理字符串数组
            String[] arr = (String[]) propertyValue;
            return Arrays.stream(arr)
                    .map(String::trim)
                    .filter(s -> !s.isEmpty())
                    .collect(Collectors.toList());
        }
        else if (propertyValue instanceof List) {
            // 处理列表类型
            return ((List<?>) propertyValue).stream()
                    .map(Objects::toString)
                    .map(String::trim)
                    .filter(s -> !s.isEmpty())
                    .collect(Collectors.toList());
        }
        else {
            // 其他类型，转换为字符串并按逗号分割
            return Arrays.stream(propertyValue.toString().split(","))
                    .map(String::trim)
                    .filter(s -> !s.isEmpty())
                    .collect(Collectors.toList());
        }
    }
}